package com.atguigu.gmall.item.rpc;

import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.item.comp.RedisDistLock;

import org.redisson.api.RCountDownLatch;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @ClassName HelloTestController
 * @Description TODO
 * @Author king
 * @Date 2022/11/9 22:35
 * @Version 1.0
 *
 *
 * 锁:
 *      1: 可重入锁
 *      2: 公平锁: 优先让等待时间最长的人抢到锁
 *      3: 读写锁: 读读无锁, 读写/写读/写写 相当于有锁
 *      4, 闭锁(CountDownLatch): 闭锁[收集七龙珠}.
 *      5, 信号量: XXX
 * 分布式锁: redisson: 基于redis做好了非常多的分布式功能.
 *
 */
@RestController
@RequestMapping("/api/inner/rpc/item")
public class HelloTestController {

    @Autowired
    StringRedisTemplate redisTemplate;
    //Lock lock = new ReentrantLock(); //java如何保证原子? 直接修改内存占位

    @Autowired
    RedisDistLock redisDistLock;

    @Autowired
    RedissonClient redissonClient;

    @Value("${server.port}")
    String port;

    @GetMapping("/longzhu")
    public Result longzhu(){

        RCountDownLatch longzhu7 = redissonClient.getCountDownLatch("longzhu7");

        longzhu7.countDown();

        return Result.ok("收集到一颗");
    }


    @GetMapping("/shenglong")
    public Result zhaohuanshenlong() throws InterruptedException {

        RCountDownLatch longzhu7 = redissonClient.getCountDownLatch("longzhu7");

        longzhu7.trySetCount(7);

        longzhu7.await();;

        return Result.ok(port + "圣龙来啦..........");
    }



    @GetMapping("/incr")
    public Result incr() throws InterruptedException {

        //String token = redisDistLock.lock();

        //获取锁
        RLock lock = redissonClient.getLock("lock");

        //阻塞式等锁
        //lock.lock();
        //lock.lock(10, TimeUnit.SECONDS);//自定义指定锁时间--不会续期

        //尝试式等锁
        boolean b = lock.tryLock();//尝试加锁
        //不会有自动续期
        //boolean b = lock.tryLock(10,TimeUnit.SECONDS);
        //boolean b = lock.tryLock(10,15,TimeUnit.SECONDS);
        if (b){
            try {
                //1,读取值
                String abc = redisTemplate.opsForValue().get("abc");
                //2,修改
                int i = Integer.parseInt(abc) + 1;
                //3,保存redis
                redisTemplate.opsForValue().set("abc", i + "");
            }finally {
                lock.unlock();
            }
        }
        //redisDistLock.unlock(token);
        return Result.ok();

    }
}
